import struct
import urllib.parse
import os
import hashlib
from threading import Lock, RLock
from memory_file import MemoryFileOpt, TransactionData
from com.config_common import ConfigBase
from com.entity.config_entity import *
from com.statistics_base import Statistics
from enum import Enum
# from memory_file import *


class SymbolEnum(Enum):
    eq = 1  # equal
    gt = 2  # greater than
    lt = 4  # less than
    ic = 8  # include


class DataSortType(Enum):
    ase = 1
    des = 2


class NumberType(Enum):
    INT = 1
    FLOAT = 2
    NOT = 0


def pack(fmt, *args):
    bytes_val = struct.pack(fmt, *args)
    return bytes_val


def unpack(fmt, bytes_val):
    struct_val = struct.unpack(fmt, bytes_val)
    return struct_val


def calcsize(fmt):
    return struct.calcsize(fmt)


def create_key(key, encode="utf-8"):
    key_num = 0
    i = len(key)
    for s in key:
        key_bytes = s.encode(encode)
        for b in key_bytes:
            key_num += (b * (10 ** i))
        i -= 1
    return key_num


def url_value(key, value):
    val = dict
    val[key] = value
    return urllib.parse.urlencode(val)


def is_num(val):
    if isinstance(val, int):
        return NumberType.INT
    elif isinstance(val, float):
        return NumberType.FLOAT
    return NumberType.NOT


def convert_num(num_type, val):
    if num_type.value == NumberType.INT.value:
        return int(val)
    elif num_type.value == NumberType.FLOAT.value:
        return float(val)
    return val


def find_bytes(context, search):
    context_p = 0
    search_p = 0
    shadow_p = 1
    shadow_next_p = 0

    while True:
        if shadow_p + shadow_next_p >= len(context) or shadow_next_p >= len(search):
            pass
        elif context[shadow_p + shadow_next_p] == search[shadow_next_p]:
            shadow_next_p += 1
        else:
            shadow_p += 1
            shadow_next_p = 0

        if context_p >= len(context) or search_p >= len(search):
            return context_p - search_p if context_p > context_p - search_p else -1
        elif context[context_p] == search[search_p]:
            context_p += 1
            search_p += 1
        else:
            context_p = shadow_p + shadow_next_p
            search_p = shadow_next_p
            shadow_p += 1
            shadow_next_p = 0
    return -1


class ConfigItem:
    _instance_lock = Lock()

    @staticmethod
    def item():
        if not hasattr(ConfigItem, "__cfg__"):
            with ConfigItem._instance_lock:
                if not hasattr(ConfigItem, "__cfg__"):
                    path, name = os.path.split(__file__)
                    ConfigItem.__cfg__ = ConfigBase(path="%s/cfg/config.yaml" % path, en=ConfigEntity())
        return ConfigItem.__cfg__


# endian_head = "<" if MemoryFileOpt.small_endian() == 0 else ">"
cfg = ConfigItem.item().config
index_max_num = 999999999
empty = ""
stat = Statistics()
delete_val = struct.pack("B", 0)
